#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@author:Gwong Zaak Liu
@interpreter version:python 3.9.13
@file:  Perpetual_Calendar.py
@time:  2022/9
"""
import pretty_errors
from calendar import Calendar
from openpyxl import Workbook
from openpyxl import load_workbook
from openpyxl.styles import Color, PatternFill, Border, Side, Font, Alignment

#########以下The_Year为输入的年份（全局变量）########
The_Year = input("请输入需要打印的年份，按回车确定：")
The_Year_str = str(The_Year)


#########以下函数分解对应年、月到6周########
def Decompose(year, month):
    # 要求传入数据格式是int
    year = int(year)
    ###根据年月变量返回各周的日期###
    c = Calendar(firstweekday=6)
    List_Of_Calendar_Date = c.monthdayscalendar(year, month)
    return List_Of_Calendar_Date


#########以下函数新建一个Workbook########
def BuildWorkbook(The_Year_Str):
    # 调用方法Workbook()，简称为wb
    WB = Workbook()
    WB.create_sheet(The_Year_Str, index=0)
    # 保存
    WB.save(The_Year_Str + '.xlsx')
    return


#########定义WriteDown函数往工作表The_Year_str写入函数值########
def WriteDown(The_Year_Str, Row, Column, Value):
    # 打开Workbook#
    workbook = load_workbook(The_Year_Str + '.xlsx')
    sheet = workbook[The_Year_Str]
    sheet.cell(row=Row, column=Column, value=Value)
    # 写入内容后，一定要保存才会生效，写入一次保存一次，以后调用只需要处理好逻辑，不用再保存
    workbook.save(The_Year_Str + '.xlsx')
    return


#########定义MergeCells函数,在工作表The_Year_str中合并单元格########
def MergeCells(The_Year_Str, start_row, start_column, end_row, end_column):
    # 打开Workbook#
    workbook = load_workbook(The_Year_Str + '.xlsx')
    sheet = workbook[The_Year_Str]
    sheet.merge_cells(start_row=start_row, start_column=start_column, end_row=end_row, end_column=end_column)
    # 写入内容后，一定要保存才会生效，写入一次保存一次，以后调用只需要处理好逻辑，不用再保存
    workbook.save(The_Year_Str + '.xlsx')
    return


#########定义FillColor函数,填充单元格颜色#########
def FillColor(The_Year_Str, row, column):
    # 打开Workbook#
    workbook = load_workbook(The_Year_Str + '.xlsx')
    sheet = workbook[The_Year_Str]
    sheet.cell(row=row, column=column).fill = PatternFill(fill_type='solid', fgColor="FFF68F")
    # 写入内容后，一定要保存才会生效，写入一次保存一次，以后调用只需要处理好逻辑，不用再保存
    workbook.save(The_Year_Str + '.xlsx')
    return


#########定义AdjustRowDimensions函数,调整行高########
def AdjustRowDimensions(The_Year_Str, row, height):
    # 打开Workbook#
    workbook = load_workbook(The_Year_Str + '.xlsx')
    sheet = workbook[The_Year_Str]
    sheet.row_dimensions[row].height = height
    # 写入内容后，一定要保存才会生效，写入一次保存一次，以后调用只需要处理好逻辑，不用再保存
    workbook.save(The_Year_Str + '.xlsx')
    return


#########定义AdjustRowDimensionsOfEachWeek函数,调整每周的行高########
def AdjustRowDimensionsOfEachWeek(The_Year_Str):
    for week in range(16):
        height = [0, 9.75, 43.5, 20.25, 29.25, 65, 29.25, 65, 29.25, 65, 29.25, 65, 29.25, 65, 29.25, 65]
        AdjustRowDimensions(The_Year_Str, week, height[week])
    print("已调整页面行高")
    return


#########定义增加边框函数AddBorder,快速增加边框#########
def AddBorder(The_Year_Str, row, column, style):
    # 打开Workbook#
    workbook = load_workbook(The_Year_Str + '.xlsx')
    sheet = workbook[The_Year_Str]
    sheet.cell(row=row, column=column).border = style
    # 写入内容后，一定要保存才会生效，写入一次保存一次，以后调用只需要处理好逻辑，不用再保存
    workbook.save(The_Year_Str + '.xlsx')
    return


#########定义Set_The_Font函数,设置每月的字体########
def Set_The_Font(The_Year_Str, row, column, font):
    # 打开Workbook#
    workbook = load_workbook(The_Year_Str + '.xlsx')
    sheet = workbook[The_Year_Str]
    sheet.cell(row=row, column=column).font = font
    # 写入内容后，一定要保存才会生效，写入一次保存一次，以后调用只需要处理好逻辑，不用再保存
    workbook.save(The_Year_Str + '.xlsx')
    return


#########定义Aligned_Format函数,设置居中对齐########
def Aligned_Format(The_Year_Str, row, column, style):
    # 打开Workbook#
    workbook = load_workbook(The_Year_Str + '.xlsx')
    sheet = workbook[The_Year_Str]
    sheet.cell(row=row, column=column).alignment = style
    # 写入内容后，一定要保存才会生效，写入一次保存一次，以后调用只需要处理好逻辑，不用再保存
    workbook.save(The_Year_Str + '.xlsx')
    return


####################################函数入口###################################
def Write_Common_Date(The_Year_Str):
    day_of_week = ['日', '一', '二', '三', '四', '五', '六']
    list_pre = ['   一月   January', '   二月   February', '   三月   March', '   四月   April', '   五月   May', '   六月   June',
                '   七月   July', '   八月   August', '   九月   September', '   十月   October', '   十一月   November',
                '   十二月   December']
    # 定义左框加粗格式#
    border_left_thick = Border(left=Side(border_style='thick', color='FF000000'),
                               right=Side(border_style='thin', color='FF000000'),
                               top=Side(border_style='thin', color='FF000000'),
                               bottom=Side(border_style='thin', color='FF000000'))
    # 定义右框加粗格式#
    border_right_thick = Border(right=Side(border_style='thick', color='FF000000'),
                                left=Side(border_style='thin', color='FF000000'),
                                top=Side(border_style='thin', color='FF000000'),
                                bottom=Side(border_style='thin', color='FF000000'))
    # 定义下中框加粗格式#
    border_middlebottom_thick = Border(bottom=Side(border_style='thick', color='FF000000'),
                                       left=Side(border_style='thin', color='FF000000'),
                                       right=Side(border_style='thin', color='FF000000'),
                                       top=Side(border_style='thin', color='FF000000'))
    # 定义下左框加粗格式#
    border_leftbottom_thick = Border(bottom=Side(border_style='thick', color='FF000000'),
                                     left=Side(border_style='thick', color='FF000000'),
                                     right=Side(border_style='thin', color='FF000000'),
                                     top=Side(border_style='thin', color='FF000000'))
    # 定义下右框加粗格式#
    border_rightbottom_thick = Border(bottom=Side(border_style='thick', color='FF000000'),
                                      left=Side(border_style='thin', color='FF000000'),
                                      right=Side(border_style='thick', color='FF000000'),
                                      top=Side(border_style='thin', color='FF000000'))
    # 定义顶框加粗格式#
    border_top_thick = Border(left=Side(border_style='thick', color='FF000000'),
                              right=Side(border_style='thick', color='FF000000'),
                              top=Side(border_style='thick', color='FF000000'),
                              bottom=Side(border_style='thin', color='FF000000'))
    # 定义所有线框为细线框格式#
    border_all_thin = Border(left=Side(border_style='thin', color='FF000000'),
                             right=Side(border_style='thin', color='FF000000'),
                             top=Side(border_style='thin', color='FF000000'),
                             bottom=Side(border_style='thin', color='FF000000'))
    # 定义title字体#
    title_font = Font(u'黑体', size=24, bold=True, italic=False, strike=False, color='000000')
    # 定义工作日的Day_of_week字体#
    Day_of_week_in_work_day_font = Font(u'黑体', size=16, bold=True, italic=False, strike=False, color='000000')
    # 定义工作日Number字体#
    Number_in_work_day_font = Font(u'黑体', size=20, bold=True, italic=False, strike=False, color='000000')
    # 定义周末的Day_of_week字体#
    Day_of_week_in_weekend_font = Font(u'黑体', size=16, bold=True, italic=False, strike=False, color='FF0000')
    # 定义周末Number字体#
    Number_in_weekend_font = Font(u'黑体', size=20, bold=True, italic=False, strike=False, color='FF0000')
    alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)
    # 调试for month in range(1,13):#
    for month in range(1, 13):
        # 获取当前月份的周数lenth#
        lenth = len(Decompose(The_Year_Str, month))
        print("---------%s年%s月有%s周---------" % (The_Year_Str, month, lenth))

        ############打印写入月历的表头、填充单元格颜色############
        for day in range(1, 8):
            WriteDown(The_Year_Str, 3, day + month * 8 - 7, day_of_week[day - 1])
            FillColor(The_Year_Str, 3, day + month * 8 - 7)
        print("写入%s月的表头" % month)
        print("填充%s月单元格的颜色" % month)

        ############写入月历的标题############
        WriteDown(The_Year_Str, 2, month * 8 - 6, The_Year_Str + list_pre[month - 1])
        print("写入%s月月历的标题" % month)
        ########合并单元格########
        MergeCells(The_Year_Str, 2, month * 8 - 6, 2, month * 8)
        print("合并%s月的单元格" % month)

        ########增加线框########
        for line in range(3, 3 + lenth * 2):
            # 中部所有细线框#
            for day in range(3, 8):
                AddBorder(The_Year_Str, line, day + month * 8 - 8, border_all_thin)
            # 左右两边所有粗线框#
            AddBorder(The_Year_Str, line, month * 8 - 6, border_left_thick)
            AddBorder(The_Year_Str, line, month * 8, border_right_thick)
        print("增加%s月细线框及左右两边粗线框" % month)
        # 下部中间所有粗线框#
        for day in range(3, 8):
            AddBorder(The_Year_Str, 3 + lenth * 2, day + month * 8 - 8, border_middlebottom_thick)
        print("增加%s月底部中央粗线框" % month)
        # 底部两角的所有粗线框#
        AddBorder(The_Year_Str, 3 + lenth * 2, month * 8 - 6, border_leftbottom_thick)
        AddBorder(The_Year_Str, 3 + lenth * 2, month * 8, border_rightbottom_thick)
        print("增加%s月底部两角粗线框" % month)
        # 顶部的所有粗线框#
        for day in range(2, 9):
            AddBorder(The_Year_Str, 2, day + month * 8 - 8, border_top_thick)
        print("增加%s月顶部粗线框" % month)
        ########定义Set_The_Font_Of_Each_Week函数,设置每月的字体########
        for day in range(2, 9):
            # 设置title字体#
            Set_The_Font(The_Year_Str, 2, month * 8 - 6, title_font)
        print("设置%s月title字体" % month)
        for day in range(3, 8):
            # 设置工作日的Day_of_week字体#
            Set_The_Font(The_Year_Str, 3, day + month * 8 - 8, Day_of_week_in_work_day_font)
            for line in range(4, 15, 2):
                # 设置工作日Number字体#
                Set_The_Font(The_Year_Str, line, day + month * 8 - 8, Number_in_work_day_font)
        print("设置%s月工作日的Day_of_week字体" % month)
        print("设置%s月工作日Number字体" % month)
        for day in range(2, 9, 6):
            # 设置周末的Day_of_week字体#
            Set_The_Font(The_Year_Str, 3, day + month * 8 - 8, Day_of_week_in_weekend_font)

            for line in range(4, 15, 2):
                # 设置周末Number字体#
                Set_The_Font(The_Year_Str, line, day + month * 8 - 8, Number_in_weekend_font)
        print("设置%s月周末的Day_of_week字体" % month)
        print("设置%s月Number字体" % month)
        #########设置每月的居中对齐########
        for line in range(2, 16):
            for day in range(2, 9):
                Aligned_Format(The_Year_Str, line, day + month * 8 - 8, alignment)
        print("%s月居中对齐" % month)

        ############写入全年每天的日期############
        # 每月写6周#
        for week in range(1, 7):
            # 防止数据越组#
            if week <= lenth:
                for day in range(1, 8):
                    date = Decompose(The_Year_Str, month)[week - 1][day - 1]
                    # 将“0”去除#
                    if date == 0:
                        date = ""
                    # print(date)
                    WriteDown(The_Year_Str, 2 + week * 2, day + month * 8 - 7, date)
        print("写入%s月的日期" % month)
    return


##################以下为主函数#################
BuildWorkbook(The_Year_str)
Write_Common_Date(The_Year_str)
AdjustRowDimensionsOfEachWeek(The_Year_str)
